package com.vp.org.web.base;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

public class BaseServlet extends HttpServlet {

    protected Map<String, String> map;

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) {
        // 初始化 map 集合
        map = new HashMap<>();

        try {
            req.setCharacterEncoding("utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        Enumeration<String> names = req.getParameterNames();

        // 除了 method 参数以为的参数都封装到 map 集合里
        String name;
        while (names.hasMoreElements()){
            name = names.nextElement();
            if (!"method".equals(name)) {
                map.put(name, req.getParameter(name));
            }
        }

        name = req.getParameter("method");

        if (name == null || name.trim().isEmpty()) {
            throw new RuntimeException("您没有传递method参数,无法确定要调用的方法!");
        }

        Class<?> c = this.getClass();

        Method method;
        try {
            method = c.getMethod(name, HttpServletRequest.class, HttpServletResponse.class);
        } catch(Exception e){
            throw new RuntimeException("您要调用的"+name+"方法,它不存在!");
        }

        // 调用 method 方法

        try {

            String result = (String) method.invoke(this, req, resp);

            /*
             * 获取请求处理方法执行后返回的字符串, 它表示转发或重定向的路径!
             * 完成转发或重定向.
             *
             *  如果用户返回的字符串为 null, 或为 "", 那么我们什么也不做!
             *
             * 查看返回的字符串中是否包含冒号, 如果没有, 表示转发
             * 如果有, 使用冒号分割字符串, 得到前缀和后缀!!
             * 其中前缀如果是 f, 表示转发, 如果是 r, 表示重定向, 后缀就是要转发或重定向的路径了!
             */

            if (result == null || result.trim().isEmpty()) {
                return;
            }

            // 如果不为空 使用冒号分割字符串, 得到前缀和后缀
            if (result.contains(":")) {
                // 获取冒号的位置
                int index = result.indexOf(":");
                // 获取前缀
                String s = result.substring(0, index);
                // 获取后缀, 即路径
                String path = result.substring(index +1);

                if(s.equalsIgnoreCase("r")){
                    // 如果前缀是 r,重定向
                    resp.sendRedirect(req.getContextPath() + path);
                }else if(s.equalsIgnoreCase("f")){
                    req.getRequestDispatcher(path).forward(req, resp);
                } else {
                    throw new RuntimeException("您指定的操作:"+s+",当前版本不支持!");
                }

            } else {
                // 没有冒号, 默认为转发
                req.getRequestDispatcher(result).forward(req, resp);
            }

        }catch(Exception e){
            throw new RuntimeException(e);
        }
    }
}